This is the documentation of the genesi of a web shop. It describes the taken steps and the features. The code is not production-ready but shows at various locations different way to do things. Contents:
The Web shop will be for selling pencils in various types. Categories: • Standard pencils • Mechnical pencils • Special pencils Variants or options: • Color (red, yellow, black, white, etc.) • Hardness (standard: HB; hard: F, H, 2H; soft: B, 2B) • Additional function (Eraser at the end, Protection cap, handle)
1.1.1 Product overview
(The product names are in German because the main language of the shop will not be English)
3 Shop Documentation, Release 0.0.1
Type Variant Color Hardness Price CHF Bleistift keine rot HB 1 Bleistift keine rot B 1 Bleistift keine rot 2B 1 Bleistift keine gelb F 1.20 Bleistift keine gelb H 1.20 Bleistift keine gelb 2H 1.20 Bleistift Gummi rot HB 1.10 Schreiner-Bleistift keine rot HB 1.80 Schreiner-Bleistift keine rot B 1.80 Bleistift keine rot HB 0.5 Bleistift Gummi rot HB 0.6 Künstler-Bleistift Griff gelb 2B 2 Künstler-Bleistift Griff rot 2B 2 Künstler-Bleistift Griff schwarz 2B 2 Minien-Bleistift keine weiss 4 Minien-Bleistift keine blau 4 Minien-Bleistift keine gelb 4 Minien-Bleistift keine rot 4 Minien-Bleistift keine silber 9 Minien-Bleistift keine schwarz 9
1.2 Personas
The following personas are defined to interact with the web shop.
1.2.1 Major customer
Eva is responsible for the ordering of office supplies in her joinery. She is ordering twice a month a large amount of various product for different users (management, back office, and production). Eva has a fix budget for the orders and she knows her way around web shops.
1.2.2 End user
Hugo is an architect and middle aged. He is drawing sketches and technical drawings but also artistically demanding pieces by hand. Thanks to the work with CAD he decovers the web and its advantages. Before he bought all his tools in a local stationery, nowadays he is ordering stuff online.
1.3 Use cases
The shop will be stripped-down to two use cases. With those use cases are all major use cases with only little modifi- cations covered. The use cases for the shop adimistration will be considered out of scope.
1.3.1 Major customer
• Ordering of a large amount of one single products or several products • Volume discount
• Splitting of oders (ev. delivery to different locations)
1.3.2 End user
• Ordering of single products • Small quantities
1.4 Design principles
The below listed points are the fundation for the implementation of the design and the layout to the shop. • Products should be in the spot light • Reduced to the essentials (typography, colors, fonts, etc.) • meaningful use of whitespaces Instead of reinventing the wheel it should be considered to use a matured front-end framework like bootstrap for the layout, especially regarding responsive design.
The used company and all data are notional. There is no exisiting connection to any existing company with the same or similar name.
2.1.1 Company name
The company name is: Pencil AG
2.1.2 Address
The complete address of the company is Pencil AG Musterstrasse 1 3000 Bern Schweiz
2.1.3 Logo
The logo used in this project is borrowed from the Tango project icon set. The file is out of the categories section, the file name of the origin file is applications-office.svg and is licensed under Public Domain.
2.2 Layout
The layout is splitted in different sections. The content of the elements, especially of the main section (content), will be definied by the later usage of the page.
7 Shop Documentation, Release 0.0.1
2.3 Sitemap
The sitemap shows the clustering of the shop at the beginning of the project.
This doesn’t mean that everything will be done. Static pages are easy to make and to maintain.
8 Kapitel 2. Web shop Design Shop Documentation, Release 0.0.1
2.4 Main page
The first draft of the main page is based on the prototype shown in section Layout, without any format- und style informationen.
2.4. Main page 9 Shop Documentation, Release 0.0.1
Loaded in a browser the initial draft of the main page looks like in the following screenshot.
10 Kapitel 2. Web shop Design KAPITEL 3
Style and design
3.1 Cascading Style Sheets
The design of the shop will be nothing fancy. The approach which was choosen will reflect the points mentioned in the Design principles section and makes heavy use of the bootstrap framework cascading style sheet. Various changes to this CSS file ensure that it matche the needs of this project.
3.2 Pages
The product page show the elements mentioned in the Product overview section.
11 Shop Documentation, Release 0.0.1
12 Kapitel 3. Style and design KAPITEL 4
Dynamics
The webshop will be a PHP application at the end. Those first steps are only covering the very basic stuff of PHP as an introduction.
4.1 Setup
The setup.yml playbook puts a simple PHP file in the root directory of the web server with the name phpinfo.php. This file displays PHP details.
Achtung: Remove this file before makeing the shop accessible by a public audience.
4.2 Current year
The first PHP element in the webshop is showing the current year in the footer of every page. With the help of this little piece of code there is no longer a need to update the year.
4.3 Navigation Menu
The basic menu was built with the following snippet. ’index.php’, ’Produkte’ => ’products.php’, ’Über uns’ => ’about.php’ ); foreach($menu as $label => $link) { echo ’
The issue with that snippet was that the CSS class was missing. In regards to a future separation and reusability an additional statements was added. This way the label of the active page is highlighted.
The data for the About page are included out of a static and plain text file.
4.5. Company details 15 Shop Documentation, Release 0.0.1
16 Kapitel 4. Dynamics KAPITEL 5
External files
5.1 Navigation Menu
The menu is outsourced in the file menu.php. ’."\n"; $part2 = ’’; $part3 = ’’."\n"; // Menu array with page title and assigned file $menu = array(’Home’ => ’index.php’, ’Produkte’ => ’products.php’, ’Über uns’ => ’about.php’ ); foreach ($menu as $label => $link) { // For the CSS only the file name without / is needed $url = trim($_SERVER[’PHP_SELF’], ’/’); if ($link == $url) { $part2 = $part2."
The “Buy Now” links are attached to the Products page. Every entry has it’s own link which lead to a detail page. The links are using hidden form elements to transfer the data. $details) { echo "
"."\n"; foreach ($details as $detail) { echo "
".$detail."
"."\n"; } echo "
"."\n"; echo ""."\n"; echo "
"."\n"; echo "
"."\n"; } ?>
And the detail page contains the code fragement mentioned below.
19 Shop Documentation, Release 0.0.1
Bemerkung: The Products page was modified in the process of the development.
6.2 Select options
The signup/billing page contains a dropdown element that all days of a month for the entry of the user’s birthday.
20 Kapitel 6. Input processing KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language. The webshop is using Javascript at a couple of places.
7.1 Simple use case
Javascript makes it easy to access elements in the DOM. Setting the focus is a nice way to support the user with input form
Another one is to check if something was entered in an input field. function validateForm() { var username = document.forms[”login”][”username”].value; if (username == null || username == “”) { document.forms[”login”][”username”].style.backgroundColor = “#FF9999”; docu- ment.forms[”login”][”username”].placeholder = “Please, your username!”; docu- ment.forms[”login”][”username”].focus(); return false; A simple message is informing the user about an action which was taken against the database. echo "";
The delete process is only executed if the user confirm to delete a record.
For additional Javascript please check the source of the index.php file and the :ref:‘webservice‘_ section.
21 Shop Documentation, Release 0.0.1
22 Kapitel 7. Javascript KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that are accessible from different pages and across multiple visits to the site.
8.1 Cookies
A cookie is used to track the last time a visitor check the front page. The cookie is set when a visitor arrives: function lastVisit($name, $expire) { $value = getDateDMY()." - ".getTimeHM(); setcookie($name, $value, time() + $expire, ’/’, $_SERVER[’SERVER_NAME’], true, true); }
In the footer of the index page the details are presented:
8.2 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available.
Included in the footer it shous the users the total of visits: echo " Total ".$_SESSION[’hits’]." visits of this page.";
23 Shop Documentation, Release 0.0.1
8.3 Language selection
8.4 User Accounts
24 Kapitel 8. Cookies and Sessions KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL. For the setup please check the Development section in this documentation.
9.1 Tables
The following tables are needed for the webshop to work. • products • customers • pencils • colors • hardness • options • users Please use the devel/webshop.sql to setup the database.
9.2 PHP
Below you find the configuration file for a default installation of the webshop. This file is a template and filled during the setup process.
if ($connection->connect_errno) { echo "Failed to connect to MariaDB/MySQL: (".$connection->connect_errno.") ".$connection->connect_error; } mysqli_report(MYSQLI_REPORT_ERROR); ?>
25 Shop Documentation, Release 0.0.1
All connections to the database are done in the same way. Below you find an example. Everything is done in the object-oriented style. connect_errno == 0) { $sql = "SELECT * FROM products"; $results = $connection->query($sql); echo $results->num_rows; $results->close(); } else { echo "Database connection error"; } ?>
26 Kapitel 9. Database KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources.
10.1 Map
Leafletjs, a JavaScript library for working with interactive maps from OpenStreetMap (OSM), is implemented as a show case for a simple web service. The basic steps to integrate a map is shown below:
...
10.2 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications.
Temperatur: $tempC °C \n"; echo "Luftfeuchtigkeit: $humidity % \n"; echo "Luftdruck: $pressure Pa
\n"; ?>
28 Kapitel 10. Web service KAPITEL 11
Data export
11.1 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP. As a showcase for that the product specifications for a given product are filled in a pdf and showed in the browser. The user can then decide to download or print the file.
11.2 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format. The format is language independent and PHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data). ... $rows = array(); $sql = "SELECT * FROM products"; $results = $connection->query($sql); while ($result = $results->fetch_object()) { $rows[] = $result; } $results->close();
// Writing all rows to a JSON file $fp = fopen(’pencils.json’, ’w’); fwrite($fp, json_encode($rows)); fclose($fp); ?> and for reading it:
29 Shop Documentation, Release 0.0.1
30 Kapitel 11. Data export KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messages as an additional feature. The MQTT messages are small
12.1 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT. Please check the Project’s README for details about the installation and the setup.
12.1.1 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol. Check if mosquitto is run- ning: $ sudo systemctl status mosquitto.service
If not, start it $ systemctl start mosquitto.service
All messages are published to the topic webshop.
12.1.2 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message.
$client = new Mosquitto\Client(CLIENT_ID); $client->connect(BROKER, PORT, 60);
$message = "Test message from webshop at ".date("Y-m-d H:i:s"); $client->publish($completeTopic, $message, 0, false); ?>
31 Shop Documentation, Release 0.0.1
12.1.3 Subscribing
To read the messages sent by the webshop, a client is needed. The Mosquitto broker contain a simple command-line tool for subscribing to various topics. $ mosquitto_sub -h localhost -t webshop/#
12.2 Email
This section doesn’t describe the installation and configuration of a local MTA. There are enough resources that contains information about the setup of postfix for local delivery only. If you want to test the email feature, add the following code in one of PHP pages.
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do. To allow sending email the following SELinux boolean needs to changed # setsebool -P httpd_can_network_connect=1 # setsebool -P httpd_can_sendmail=1
32 Kapitel 12. Messaging KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site. For small projects arrays with string can work but this is not very efficient and user-friendly. With Gettext is a toolset available that provide a framework to produce multi-lingual content in a wide area of programming languages. Make sure that the php-gettext package is available on your system. If not install it. $ sudo yum -y install php-php-gettext
Check if gettext support is available.
Make sure that all locales your want are available on the server: locale-a
The first step is to mark all string which should be translatable as shown below. For further details please refer to the Gettext documentation. echo _(’Some text’);
The next step is to extract all strings.: xgettext --from-code=UTF-8 -o locale/webshop.pot *.php scripts/*.php
To re-generate the file after an update, join the strings. xgettext -j --from-code=UTF-8 -o locale/webshop.pot *.php scripts/*.php
For every language a po file is needed for the transations. Generate it with the command mentioned below: msginit --no-translator -l de_CH -o locale/de_CH.po -i locale/webshop.pot
Once created there are only updates of the message catalog needed in the futures: msgmerge -U locale/de_CH.po locale/webshop.pot
If you re finish, create the mo file for the specific language.
For a more detailed intro, check this article on Zend Developer Zone.
14.2 Content
To fill the template with data, all wished variables needs to be defined in a seperate PHP file.
// Create a title $title = "Simple sample page";
// Create the content of the page $content = "Some sample text to show";
// Assign values to the Savant instance $tpl->title = $title; $tpl->content = $content;
// Define the template source file to show $tpl->display(’simple.tpl.php’); ?>
35 Shop Documentation, Release 0.0.1
The webshop contains a page (master)
36 Kapitel 14. Templates KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop.
15.1 Web server
Instead of Apache the project is running on Lighttpd. The reasons are that Lighttpd provides faster setup, easier configuration, and better performance. Lighttpd is running with FastCGI. The path of the web server is /var/www/lighttpd/ and the SELinux configuration are still the defaults. The web server is running in SSL-only mode and the certificate is generated during the server setup process.
15.2 Database server
For persistence storage the drop-in replacement MariaDB is used. MySQL will work to but this is not tested. phpMyAd- min is available under /phpmyadmin/ on the web server, beside the command-line tools, for easy administration. The default credentials for phpMyAdmin are root/webshop or the entry you made in the Ansible playbook devel/variables/sensitive.yml
15.3 Versions
The web shop is built with the below listed components and tested. Other releases can be used and may work but this will not be tested. Probably it will work with different releases. • Operating system: Fedora 20 • Kernel: 3.13.5-202.fc20.x86_64 • Lighttpd: 1.4.34 • PHP: 5.5.7 • MariaDB: 5.5.34 For communication postfix and mosquitto are needed additionally.
37 Shop Documentation, Release 0.0.1
15.4 Setup infrastructure
15.4.1 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across different systems Ansible is used as configuration management solution. All needed steps of the installation are automated. The configuration doesn’t differentiate between local or remote installations. This matters only for the deployment of the web content. For local development it’s possible to use an LX container. $ sudo ansible-playbook devel/container.yml
To get everything running some additional steps (check the network inside the container, generate keys, etc.) are needed. After you are done, check it: $ sudo ansible webshop -m setup
From the management system: $ sudo ssh-copy-id -i /root/.ssh/id_rsa.pub root@[IP address of your managed node]
The configuration of Ansible itself (adding the system to /etc/ansible/hosts and copying the SSH keys) is not documented at this place. There are various resources available, like here. All playbooks are located in the folder devel. Start the setup with the command shown below: $ sudo ansible-playbook devel/setup.yml
The used group name in /etc/ansible/hosts is: webshop If the setup completes without errors, then the web server is accessible and show a default page. Please keep in mind, that the server is only accessible over https://, unencrypted traffic is not allowed.
15.4.2 Deployment/Setup website
For the simple deployment of the lastest version of the shop a playbook called deploy.yml is provided. This playbook put all files in place. $ sudo ansible-playbook devel/deploy.yml
To full deploy the webshop all tables in the database must exist. The file webshop.sql contains all needed SQL commands and sample data for the web application. It’s possible to deploy the website manually but this is not recommended. A couple of files are depending on templates which are created during the deployment. It’s also not recommanded to clone everything into your webserver root. This would save you the trouble of doing it by hand but third-party features are missing then. Those missing parts are the template engine, the pdf generation, the connection to Openstreetmap, and probably other things not mentioned here.
15.5 Git respository
All project relevante informations (Source code, templates, documentation, etc.) is located in a public Git repository on Github.
38 Kapitel 15. Development Shop Documentation, Release 0.0.1
15.6 Documentation
The documentation is using reStructuredText as markup language. For a local build Sphinx is needed. Sphinx is available in the Fedora Package Collection and can be installed with yum or any other package management tool: # yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs: $ cd docs $ make html
The output is stored under docs/_build/html. After every push to Github a hook launch a rebuild of the documentation. The latest release will be published on Read the Docs automatically. https://shop.rtfd.org/